package com.hwhy.systemmonitoring.common.util;

import com.hwhy.systemmonitoring.entity.*;
import com.sun.management.OperatingSystemMXBean;
import oshi.hardware.CentralProcessor;
import oshi.hardware.CentralProcessor.TickType;
import oshi.hardware.GlobalMemory;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;

import java.lang.management.ManagementFactory;
import java.util.Date;
import java.util.LinkedList;
import java.util.Properties;
import java.util.concurrent.TimeUnit;


/**
 * Java系统监控测试类
 *
 * @author LIFULIN
 * @className SystemInfoUtil
 * @description TODO Java系统监控测试类
 * @date 2020/4/28-18:28
 */
public class SystemInfoUtil {
    private static final long serialVersionUID = 1L;
    /**
     * 休眠时间
     */
    private static final int OSHI_WAIT_SECOND = 1;

    /**
     * 获取服务器信息
     */
    public static Sys setSysInfo() {
        Sys sys = new Sys();
        Properties props = System.getProperties();
        //服务器名称
        sys.setComputerName(IpUtil.getHostName());
        //服务器Ip
        sys.setComputerIp(IpUtil.getInet4Address());
        //项目路径
        sys.setUserDir(props.getProperty("user.dir"));
        //操作系统
        sys.setOsName(props.getProperty("os.name"));
        //系统架构
        sys.setOsArch(props.getProperty("os.arch"));
        return sys;
    }

    /**
     * 获取cpu使用率
     */
    public static double getCpuUsage() {
        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
        //CPU总的使用率
        double cpuLoad = osmxb.getSystemCpuLoad();
        //第一次获取为0，重新获取
        if (cpuLoad == 0) {
            cpuLoad = osmxb.getSystemCpuLoad();
        }
        return ArithUtil.round(ArithUtil.mul(cpuLoad, 100), 2);
    }

    /**
     * 获取CPU信息
     */
    public static Cpu setCpuInfo(CentralProcessor processor) {
        //返回信息
        Cpu cpu = new Cpu();
        // CPU信息
        long[] prevTicks = processor.getSystemCpuLoadTicks();
        //睡眠1秒
        try {
            TimeUnit.SECONDS.sleep(OSHI_WAIT_SECOND);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long[] ticks = processor.getSystemCpuLoadTicks();
        double nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()];
        double irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()];
        double softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()];
        double steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()];
        double systotal = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()];
        double user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()];
        double iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()];
        double idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];
        double totalCpu = user + nice + systotal + idle + iowait + irq + softirq + steal;
        //核心数
        cpu.setCpuNum(processor.getLogicalProcessorCount());
        //CPU总的使用率
        cpu.setTotal(ArithUtil.round(ArithUtil.div(totalCpu, 10, 2), 2) + "%");
        //CPU系统使用率
        cpu.setSystotal(ArithUtil.round(ArithUtil.mul(systotal / totalCpu, 100), 2) + "%");
        //CPU用户使用率
        cpu.setUsed(ArithUtil.round(ArithUtil.mul(user / totalCpu, 100), 2) + "%");
        //CPU当前等待率
        cpu.setWait(ArithUtil.round(ArithUtil.mul(iowait / totalCpu, 100), 2) + "%");
        //CPU当前空闲率
        cpu.setFree(ArithUtil.round(ArithUtil.mul(idle / totalCpu, 100), 2) + "%");
        return cpu;
    }

    /**
     * 获取内存使用率
     *
     * @return
     */
    public static double getMemUsage() {
        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
        double totalvirtualMemory = osmxb.getTotalPhysicalMemorySize();
        double freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize();
        double value = ArithUtil.div(freePhysicalMemorySize, totalvirtualMemory, 4);
        return ArithUtil.mul(ArithUtil.round(1 - value, 4), 100);
    }

    /**
     * 获取内存信息
     */
    public static Mem setMemInfo(GlobalMemory memory) {
        //返回实体
        Mem mem = new Mem();
        //内存总量
        double total = ArithUtil.div(memory.getTotal(), (1024 * 1024 * 1024), 2);
        //已用内存
        double use = (memory.getTotal() - memory.getAvailable());
        double used = ArithUtil.div(use, (1024 * 1024 * 1024), 2);
        //剩余内存
        double free = ArithUtil.div(memory.getAvailable(), (1024 * 1024 * 1024), 2);
        //内存使用率
        double usage = ArithUtil.mul(ArithUtil.div(used, total, 4), 100);
        mem.setTotal(total + "GB");
        mem.setUsed(used + "GB");
        mem.setFree(free + "GB");
        mem.setUsage(usage + "%");
        return mem;
    }

    /**
     * 获取Java虚拟机信息
     */
    public static Jvm setJvmInfo() {
        Jvm jvm = new Jvm();
        Properties props = System.getProperties();
        //当前JVM占用的内存总数(M)
        double total = ArithUtil.div(Runtime.getRuntime().totalMemory(), (1024 * 1024), 10);
        //JVM最大可用内存总数(M)
        double max = ArithUtil.div(Runtime.getRuntime().maxMemory(), (1024 * 1024), 2);
        //JVM空闲内存(M)
        double free = ArithUtil.div(Runtime.getRuntime().freeMemory(), (1024 * 1024), 2);
        //JVM使用内存
        double used = ArithUtil.div(total - free, (1024 * 1024), 2);
        //内存使用率
        double usage = ArithUtil.mul(ArithUtil.div(total - free, total, 4), 100);
        //JDK版本
        String version = props.getProperty("java.version");
        //JDK路径
        String home = props.getProperty("java.home");
        //获取JDK名称
        String vmName = ManagementFactory.getRuntimeMXBean().getVmName();
        //JDK启动时间
        long stime = ManagementFactory.getRuntimeMXBean().getStartTime();
        String starttime = StringUtil.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date(stime));
        //JDK运行时间
        long rtime = ManagementFactory.getRuntimeMXBean().getStartTime();
        String runtime = DateUtil.getDatePoor(new Date(), new Date(rtime));
        jvm.setTotal(total + "M");
        jvm.setMax(max + "M");
        jvm.setFree(free + "M");
        jvm.setUsed(used + "M");
        jvm.setUsage(usage + "%");
        jvm.setVersion(version);
        jvm.setHome(home);
        jvm.setGetName(vmName);
        jvm.setGetStartTime(starttime);
        jvm.setGetRunTime(runtime);
        return jvm;
    }

    /**
     * 获取磁盘信息
     */
    public static LinkedList<SysFile> setSysFiles(OperatingSystem os) {
        //返回数组
        LinkedList<SysFile> sysFileList = new LinkedList<>();
        FileSystem fileSystem = os.getFileSystem();
        OSFileStore[] fsArray = fileSystem.getFileStores();
        for (OSFileStore fs : fsArray) {
            long free = fs.getUsableSpace();
            long total = fs.getTotalSpace();
            long used = total - free;
            if (total > 0) {
                SysFile sysFile = new SysFile();
                //盘符路径
                sysFile.setDirName(fs.getMount());
                //盘符类型
                sysFile.setSysTypeName(fs.getType());
                //文件类型
                sysFile.setTypeName(fs.getName());
                //总大小
                sysFile.setTotal(StringUtil.convertFileSize(total));
                //剩余大小
                sysFile.setFree(StringUtil.convertFileSize(free));
                //已经使用量
                sysFile.setUsed(StringUtil.convertFileSize(used));
                //资源的使用率
                sysFile.setUsage(ArithUtil.mul(ArithUtil.div(used, total, 4), 100) + "%");
                sysFileList.add(sysFile);
            }
        }
        return sysFileList;
    }


}
